#include "Q3OObjectData.h"
#define DEBUG_
#define DEBUG2_
Q3OObjectData::Q3OObjectData( )
	:RawObjectData()
{
	maxBytes = 0;
	currByte = 0;
	readFile = new ifstream();
	majorVersion = 0;
	minorVersion = 0;
	facesCount = 0;
};

Q3OObjectData::~Q3OObjectData( )
{
	delete readFile;
};

bool Q3OObjectData::IsVersionAtLeast(unsigned char major,unsigned char minor)
{
	//cout <<"Version: " <<majorVersion<<"."<<minorVersion<<endl;
	if( majorVersion > major || (majorVersion == major && minorVersion >= minor ) )
		return true;
	return false;
}


bool Q3OObjectData::OpenFile(string FileName)
{
	readFile->open(FileName.c_str(), ios::binary);
	return readFile->is_open();
}

long Q3OObjectData::ReadSize( )
{
	// get length of file:
	long size = 0;
	readFile->seekg (0, ios::end);
	size = readFile->tellg();
	readFile->seekg (0, ios::beg);
	return size;
}


bool Q3OObjectData::ReadBlock( char *out ,unsigned long size )
{
	//cout <<"ReadBlock#tellg"<<endl;
	//currByte = readFile.tellg();
	//cout <<"ReadBlock#read"<<endl;
	if(!readFile->read(out, size) && readFile->eof())
		  return false;

	currByte += size;
	//cout <<"ReadBlock#seekg"<<endl;
	readFile->seekg(currByte);
	//cout <<"ReadBlock#return"<<endl;
	return true;
}

char* Q3OObjectData::ReadString( )
{
	long Count = 0;
	char *out;

	while(readFile->get() != 0)
		Count++;
	Count++;

	readFile->seekg(currByte);
	out = new char[Count];

	for( int i = 0;i < Count;i++ )
		out[i] = readFile->get();

	currByte += Count;
	readFile->seekg(currByte);

	return out;
}

////////////////////////////////////////////////////////////////////////
//q3o reading  functions
////////////////////////////////////////////////////////////////////////

bool Q3OObjectData::q3o_readHeader(Q3O_HEADER *header)
{
#if DEBUG2
	cout <<"\n\n\t > Read Header..."<<endl;
#endif
	if( !ReadBlock( header->signature , 8 ) )
		return false;
	#if DEBUG2
	cout <<"q3o_readHeader:signature_readed: "<<endl;
#endif

	if( !ReadBlock( header->version , 2 ) )
		return false;
	#if DEBUG2
	cout <<"q3o_readHeader:version_readed: "<<endl;
#endif

	if( !ReadBlock( ( char *) &header->numberMeshes , sizeof(int) ) )
		return false;
	#if DEBUG2
	cout <<"q3o_readHeader:numberMeshes_readed:\t "<<header->numberMeshes<<endl;
#endif

	if( !ReadBlock( ( char *) &header->numberMaterials, sizeof(int) ) )
		return false;
	#if DEBUG2
	cout <<"q3o_readHeader:numberMaterials_readed:\t "<<header->numberMaterials<<endl;

#endif

	if( !ReadBlock( ( char *) &header->numberTextures , sizeof(int) ) )
		return false;
	#if DEBUG2
	cout <<"q3o_readHeader:numberTextures_readed:\t "<<header->numberTextures<<endl;
#endif

	#if DEBUG2
	cout <<"BYTES READED UNTIL NOW! \t[ "<<currByte<<" ]"<<endl;
#endif

	return true;
}

bool Q3OObjectData::q3o_readChunkType(char *c)
{
	if( !ReadBlock( c , 1 ) )
		return false;
	char cstr[2];
	cstr[0] = (*c);
	cstr[1] = '\0';

	#if DEBUG2
	cout <<"\n\n\t > Read ChunkType..."<<endl;
	cout <<"q3o_readChunkType:ChunkType_readed: "<<(int)cstr[0]<<endl;
#endif

	return true;
}

bool Q3OObjectData::q3o_readMeshChunk(Q3O_MESH *mesh, bool withTexture)
{
	#if DEBUG2
	cout <<"\n\n\t > Read MeshChunk..."<<endl;
#endif
	if( !ReadBlock( (char *) &mesh->numberVertices , sizeof(long) ) )
		return false;
	#if DEBUG2
	cout <<"q3o_readMeshChunk:numberVertices_readed: "<<mesh->numberVertices<<endl;
#endif

	mesh->vertices = new Q3O_VERTEX[mesh->numberVertices];
	if( !ReadBlock( (char *) mesh->vertices , mesh->numberVertices * sizeof(Q3O_VERTEX) ) )
		return false;
	#if DEBUG2
	cout <<"q3o_readMeshChunk:vertices_readed"<<endl;
	cout <<"BYTES READED UNTIL NOW! \t[ "<<currByte<<" ]"<<endl;
#endif

	if( !ReadBlock( (char *) &mesh->numberFaces , sizeof(long) ) )
		return false;
	#if DEBUG2
	cout <<"q3o_readMeshChunk:numberFaces_readed: "<<mesh->numberFaces<<endl;
#endif
	facesCount += mesh->numberFaces;

	mesh->faceShapes = new short[mesh->numberFaces];
	if( !ReadBlock( (char *) mesh->faceShapes , mesh->numberFaces * sizeof(short) ) )
		return false;
	#if DEBUG2
	cout <<"q3o_readMeshChunk:faceShapes_readed"<<endl;
	cout <<"BYTES READED UNTIL NOW! \t[ "<<currByte<<" ]"<<endl;
#endif



	mesh->faces = new Q3O_FACE[mesh->numberFaces];

	for( int i = 0;i< mesh->numberFaces;i++)
	{
		if( mesh->faceShapes[i] != 3 )
		{
			#if DEBUG2
			cout << "Flache "<<i<<" ungleich 3 Punkte: "<<mesh->faceShapes[i]<<endl;
#endif
		}
	}


	for( int i = 0;i< mesh->numberFaces;i++)
	{
		if( mesh->faceShapes[i] != 3 )
		{
			#if DEBUG2
			cout << "Eine Polygonflaeche mit mehr oder weniger als 3 Punkten wurde gefunden...\n-> break converting !!!"<<endl;
#endif
			return false;
		}

		mesh->faces[i].vertices = new int[mesh->faceShapes[i]];
		if( !ReadBlock( (char *) mesh->faces[i].vertices , mesh->faceShapes[i] * sizeof(int) ) )
			return false;
	}
	#if DEBUG2
	cout <<"q3o_readMeshChunk:faces[i].vertices_readed"<<endl;
	cout <<"BYTES READED UNTIL NOW! \t[ "<<currByte<<" ]"<<endl;
#endif


	mesh->materialIndices = new unsigned int[mesh->numberFaces];
	if( !ReadBlock( (char *) mesh->materialIndices , mesh->numberFaces * sizeof(unsigned int) ) )
		return false;
	#if DEBUG2
	cout <<"q3o_readMeshChunk:materialIndices_readed"<<endl;
	cout <<"BYTES READED UNTIL NOW! \t[ "<<currByte<<" ]"<<endl;
#endif


	if( !ReadBlock( (char *) &mesh->numberNormals , sizeof(unsigned long) ) )
		return false;
	#if DEBUG2
	cout <<"q3o_readMeshChunk:numberFaceNormals_readed: "<<mesh->numberNormals<<endl;
#endif

	mesh->normals = new Q3O_VERTEX[mesh->numberNormals];
	if( !ReadBlock( (char *) mesh->normals , mesh->numberNormals * sizeof(Q3O_VERTEX) ) )
		return false;
	#if DEBUG2
	cout <<"q3o_readMeshChunk:FaceNormal_readed"<<endl;
	cout <<"BYTES READED UNTIL NOW! \t[ "<<currByte<<" ]"<<endl;
#endif

	if( !ReadBlock( (char *) &mesh->numberTextureCoordinates , sizeof(long) ) )
		return false;
	#if DEBUG2
	cout <<"q3o_readMeshChunk:numberTextureCoordinates_readed: "<<mesh->numberTextureCoordinates<<endl;
#endif

	if( withTexture && mesh->numberTextureCoordinates > 0 )
	{
		mesh->textureCoordinates = new Q3O_TEX_UV[mesh->numberTextureCoordinates];
		if( !ReadBlock( (char *) mesh->textureCoordinates , mesh->numberTextureCoordinates * sizeof(Q3O_TEX_UV) ) )
			return false;
		#if DEBUG2
	cout <<"q3o_readMeshChunk:textureCoordinates_readed"<<endl;
	cout <<"BYTES READED UNTIL NOW! \t[ "<<currByte<<" ]"<<endl;
#endif

		mesh->textureIndices = new Q3O_FACE[mesh->numberFaces];
		for( int i = 0;i< mesh->numberFaces;i++)
		{
			mesh->textureIndices[i].vertices = new int[mesh->faceShapes[i]];
			if( !ReadBlock( (char *) mesh->textureIndices[i].vertices , mesh->faceShapes[i] * sizeof(int) ) )
				return false;
		}
		#if DEBUG2
	cout <<"q3o_readMeshChunk:textureIndices[i].vertices_readed"<<endl;
	cout <<"BYTES READED UNTIL NOW! \t[ "<<currByte<<" ]"<<endl;
#endif
	}
	else
	{
		mesh->numberTextureCoordinates = 0;// zur sicherheit, da sowieso keine textur vorhanden ist.
	}

	if( !ReadBlock( (char *) &mesh->centerOfMass , sizeof(Q3O_VERTEX) ) )
		return false;
	#if DEBUG2
	cout <<"q3o_readMeshChunk:centerOfMass_readed"<<endl;
	cout <<"CENTER [ "<<mesh->centerOfMass.xyz[0]<<" | "<<mesh->centerOfMass.xyz[1]<<" | "<<mesh->centerOfMass.xyz[2]<<" ]"<<endl;

#endif

	if( !ReadBlock( (char *) mesh->boundingBox , 6 * sizeof(float) ) )
		return false;
	#if DEBUG2
	cout <<"q3o_readMeshChunk:boundingBox_readed"<<endl;
	cout <<"BYTES READED UNTIL NOW! \t[ "<<currByte<<" ]"<<endl;
	cout <<"BOX1 [ "<<mesh->boundingBox[0]<<" | "<<mesh->boundingBox[1]<<" | "<<mesh->boundingBox[2]<<" ]"<<endl;
	cout <<"BOX2 [ "<<mesh->boundingBox[3]<<" | "<<mesh->boundingBox[4]<<" | "<<mesh->boundingBox[5]<<" ]"<<endl;

#endif

	// new format specification

	if( IsVersionAtLeast (3,1) )
	{
		#if DEBUG2
	cout <<" __________________Format Specific with Minor > 0 => read TriFlags___________________"<<endl;

#endif
		for( int i = 0;i< mesh->numberFaces;i++)
		{
			if( !ReadBlock( (char*) &mesh->faces[i].flags , sizeof(unsigned char) ) )
				return false;
			//cout <<"\t\tTRI_FLAGS: [ "<<(int)mesh->faces[i].flags<<" ]"<<endl;
		}
	}

	return true;
}

bool Q3OObjectData::q3o_readMaterialChunk( Q3O_MATERIAL *mat )
{
	#if DEBUG2
	cout <<"\n\n\t > Read MaterialChunk..."<<endl;
#endif
	char *c = ReadString();
	mat->materialName.insert(0,c);
	#if DEBUG2
	cout <<"Material Name: "<<mat->materialName<<endl;
#endif

	if( !ReadBlock( (char *) &mat->ambientColor , sizeof(Q3O_VERTEX) ) )
		return false;
	#if DEBUG2
	cout <<"q3o_readMaterialChunk:ambientColor_readed"<<endl;
	cout <<"BYTES READED UNTIL NOW! \t[ "<<currByte<<" ]"<<endl;
#endif

	if( !ReadBlock( (char *) &mat->diffuseColor , sizeof(Q3O_VERTEX) ) )
		return false;
	#if DEBUG2
	cout <<"q3o_readMaterialChunk:diffuseColor_readed"<<endl;
	cout <<"BYTES READED UNTIL NOW! \t[ "<<currByte<<" ]"<<endl;
#endif

	if( !ReadBlock( (char *) &mat->specularColor , sizeof(Q3O_VERTEX) ) )
		return false;
	#if DEBUG2
	cout <<"q3o_readMaterialChunk:specularColor_readed"<<endl;
	cout <<"BYTES READED UNTIL NOW! \t[ "<<currByte<<" ]"<<endl;
#endif

	if( !ReadBlock( (char *) &mat->transparency , sizeof(float) ) )
		return false;
	#if DEBUG2
	cout <<"q3o_readMaterialChunk:transparency_readed: "<<mat->transparency<<endl;
	cout <<"BYTES READED UNTIL NOW! \t[ "<<currByte<<" ]"<<endl;
#endif

	if( !ReadBlock( (char *) &mat->textureIndices , sizeof(int) ) )
		return false;
	#if DEBUG2
	cout <<"q3o_readMaterialChunk:textureIndices_readed: "<<mat->textureIndices<<endl;
	cout <<"BYTES READED UNTIL NOW! \t[ "<<currByte<<" ]"<<endl;
#endif

	return true;
}

bool Q3OObjectData::q3o_readTextureChunk( Q3O_TEXTURE *tex )
{
	#if DEBUG2
	cout <<"\n\n\t > Read TextureChunk..."<<endl;
#endif
	char *c = ReadString();
	tex->textureName.insert(0,c);
	#if DEBUG2
	cout <<"Texture Name: "<<tex->textureName<<endl;
#endif

	if( !ReadBlock( (char *) &tex->textureWidth , sizeof(int) ) )
		return false;
	//cout <<"q3o_readTextureChunk:textureWidth_readed: \t"<<tex->textureWidth<<endl;
	#if DEBUG2
	cout <<"BYTES READED UNTIL NOW! \t[ "<<currByte<<" ]"<<endl;
#endif

	if( !ReadBlock( (char *) &tex->textureHeight , sizeof(int) ) )
		return false;
	//cout <<"q3o_readTextureChunk:textureHeight_readed \t"<<tex->textureHeight<<endl;
	#if DEBUG2
	cout <<"BYTES READED UNTIL NOW! \t[ "<<currByte<<" ]"<<endl;
#endif

	if( IsVersionAtLeast (3,3) )
	{
		if( !ReadBlock( (char *) &tex->xRepeat , sizeof(int) ) )
			return false;
		//cout <<"q3o_readTextureChunk:xRepeat_redead \t"<<tex->xRepeat<<endl;
		#if DEBUG2
	cout <<"BYTES READED UNTIL NOW! \t[ "<<currByte<<" ]"<<endl;
#endif

		if( !ReadBlock( (char *) &tex->yRepeat , sizeof(int) ) )
			return false;
		//cout <<"q3o_readTextureChunk:yRepeat_redead \t"<<tex->yRepeat<<endl;
		#if DEBUG2
	cout <<"BYTES READED UNTIL NOW! \t[ "<<currByte<<" ]"<<endl;
#endif
	}

	//cout <<tex->texture<<endl;
	tex->texture = new Q3O_PIXEL[tex->textureWidth*tex->textureHeight];
	//cout <<tex->texture<<endl;
	if( !ReadBlock( (char *) tex->texture , tex->textureWidth*tex->textureHeight*sizeof(Q3O_PIXEL) ) )
		return false;

	#if DEBUG2
	cout <<"q3o_readTextureChunk:texture_readed"<<endl;
	cout <<"BYTES READED UNTIL NOW! \t[ "<<currByte<<" ]"<<endl;
#endif

	return true;
}


bool Q3OObjectData::loadObject( string filename )
{
	Q3O_HEADER 				header;
	vector<Q3O_MESH*> 		meshes;
	vector<Q3O_MATERIAL*> 	materials;
	vector<Q3O_TEXTURE*> 	textures;
	_filename = filename;

	//////////////////////////////////////////
	// Prepare q3o File and Open Header
	filename = "Release/modells/" + filename;
	if( !OpenFile( filename ) )//------------------------						| Try to Open the File
	{
	cout <<"Cannot open File: "<<filename<<endl;
		return -1;
	}
	cout <<"\n\n\n\n[--- File opend to read: " << filename << " ---]"<<endl;
	maxBytes = ReadSize( );//------------------------				| Read the Filesize and memory it

	if( !q3o_readHeader(&header) )//------------------------					| Read the Header Information
	{
		cout<<"Cannot read Header"<<endl;
		return -1;
	}
	majorVersion = (unsigned char)(header.version[0]);
	minorVersion = (unsigned char)(header.version[1]);
#if DEBUG2
	cout << "MajorVersion: " << majorVersion<<endl;
	cout << "MinorVersion: " << minorVersion<<endl;
#endif

	meshes.reserve(header.numberMeshes);
	materials.reserve(header.numberMaterials);
	textures.reserve(header.numberTextures);
	//////////////////////////////////////////
	// Read Object Data from File ( optional: write them to the database )
	for( int i = 0;i < 3;i++)
	{
		if( currByte == maxBytes )
			break;
		char chunk_type;
		if( !q3o_readChunkType(&chunk_type) )
		{
			cout<<"Cannot read Chunk Type"<<endl;
			return -1;
		}

		if( chunk_type == 'm' )
		{
			for( int j = 0;j < header.numberMeshes;j++ )
			{
				Q3O_MESH *mesh = new Q3O_MESH;
				if( !q3o_readMeshChunk(mesh, ( header.numberTextures > 0 ) ) )
				{
					cout<<"Cannot read Mesh Chunk"<<endl;
					return -1;
				}
				meshes.push_back( mesh );
			}
#if DEBUG2
	cout <<"+++++++++++ FACES_REDEAD: " << facesCount << " +++++++++++"<<endl;
#endif
		}

		if( chunk_type == 'c' )
		{
			for( int j = 0;j < header.numberMaterials;j++ )
			{
				Q3O_MATERIAL *mat = new Q3O_MATERIAL;
				if( !q3o_readMaterialChunk(mat) )
				{
					cout<<"Cannot read Material Chunk"<<endl;
					return -1;
				}
				materials.push_back( mat );
			}
		}

		if( chunk_type == 't' )
		{
			for( int j = 0;j < header.numberTextures;j++ )
			{
				Q3O_TEXTURE *tex = new Q3O_TEXTURE;
				if( !q3o_readTextureChunk(tex) )
				{
					cout<<"Cannot read Texture Chunk"<<endl;
					return -1;
				}
				textures.push_back( tex );
			}
		}
	}
#if DEBUG2
	cout <<endl<<endl<< "[--- File Successfuly Readed ! ---]\n\n";//------------------------		| Happy End ;-)
#endif

	try
	{
		////////////////////////// SAVE TEXTURE
		_textures.reserve( header.numberTextures );
		TextureData* tex;
		Q3O_TEXTURE *t;
		for( int i = 0;i < header.numberTextures;i++ )
		{
			t = textures.at(i);
			tex = new TextureData( t->textureName, t->xRepeat,t->yRepeat);
			_texturesLoader->LOAD_Q3O_TEX( t, t->textureName );
			tex->setIntTexID(_texturesLoader->getIntID(t->textureName));
			_textures.push_back(tex);
		}
		#if DEBUG2
	cout << ">>> Textures Loaded in Structure"<<endl;
#endif
		////////////////////////// SAVE MATERIAL
		_materials.reserve( header.numberMaterials );
		MaterialData* mat;
		Q3O_MATERIAL *m;
		TextureData* texTmp = NULL;
		for( int i = 0;i < header.numberMaterials;i++ )
		{
			m = materials.at(i);
			if( header.numberTextures > 0 && m->textureIndices >= 0 )
				texTmp = _textures[m->textureIndices];
			mat = new MaterialData(
								m->materialName,
								new Color(m->ambientColor.xyz[0],m->ambientColor.xyz[1],m->ambientColor.xyz[2],1.0),
								new Color(m->diffuseColor.xyz[0],m->diffuseColor.xyz[1],m->diffuseColor.xyz[2],1.0),
								new Color(m->specularColor.xyz[0],m->specularColor.xyz[1],m->specularColor.xyz[2],1.0),
								new float(m->transparency),
								texTmp
			);
			_materials.push_back( mat );
			#if DEBUG2
	cout <<"\t\t->Ambient: ("<<m->ambientColor.xyz[0]<<" | "<<m->ambientColor.xyz[1]<<" | "<<m->ambientColor.xyz[2]<<" )"<<endl;
			cout <<"\t\t->Diffuse: ("<<m->diffuseColor.xyz[0]<<" | "<<m->diffuseColor.xyz[1]<<" | "<<m->diffuseColor.xyz[2]<<" )"<<endl;
			cout <<"\t\t->Specular: ("<<m->specularColor.xyz[0]<<" | "<<m->specularColor.xyz[1]<<" | "<<m->specularColor.xyz[2]<<" )"<<endl;

#endif
		}

		#if DEBUG2
	cout << ">>> Materials Loaded in Structure"<<endl;
#endif
		////////////////////////// SAVE MESHES
		Vector3 boxMin,boxMax;

		_meshes.reserve( header.numberMeshes );
		MeshData* tmp;
		TriangleData *tri;
		Q3O_VERTEX *vert;
		Q3O_TEX_UV *texUV;
		Q3O_MESH *me;
		Q3O_FACE *face;
		Q3O_FACE *texFace;
		char *strBuff = new char[11];
		//cout <<"all pointers defined"<<endl;

		//-- BK: 8.9.08 : to put the transparency meshes and trinagles on the end of the list



		list<MeshData*> transparencyMeshes;
		bool meshIsTransparency = false;
		for( int i = 0;i < header.numberMeshes;i++ )
		{
			meshIsTransparency = false;
			// fuer das hier erzeugt mesh einfach als Namen die Integer Nummer nehemn
			//cout<<"_begin_of_mesh_"<<i<<"_generating_"<<endl;

			sprintf(strBuff,"%d ",i);
			string str;
			str.insert(0,strBuff);
			#if DEBUG2
	cout<<"_number_of_mesh_"<<i<<"_generated_"<<endl;
#endif

			// neuen mesh erzeugen
			tmp = new MeshData(str);
			me = meshes.at(i);
			//cout<<"_meshData_"<<i<<"_memory_allocated_"<<endl;







			// vertices aus Q3O Struktur auslesen und diese in this.vertices Objekt Liste sichern!
			int max = me->numberVertices;// max vertices
			tmp->_vertices.reserve(me->numberVertices);
			for( int j = 0;j < max;j++ )
			{
				//cout <<"VERTEX: [ " << vert->xyz[0] << " , " << vert->xyz[1] << " , " << vert->xyz[2] << " ]"<<endl;
				vert = &me->vertices[j];// zugriff variable

				// Bounding Box!
				if( vert->xyz[0] < boxMin.getX() )
					boxMin.setX(vert->xyz[0]);

				if( vert->xyz[1] < boxMin.getY() )
					boxMin.setY(vert->xyz[1]);

				if( vert->xyz[2] < boxMin.getZ() )
					boxMin.setZ(vert->xyz[2]);

				if( vert->xyz[0] > boxMax.getX() )
					boxMax.setX( vert->xyz[0] );

				if( vert->xyz[1] > boxMax.getY() )
					boxMax.setY( vert->xyz[1] );

				if( vert->xyz[2] > boxMax.getZ() )
					boxMax.setZ( vert->xyz[2] );

				tmp->_vertices.push_back( new VertexData( new Vector3( vert->xyz[0], vert->xyz[1],vert->xyz[2] ) ) );
				//cout<<"->    "<<vert->xyz[0]<<"|"<<vert->xyz[1]<<"|"<<vert->xyz[2]<<endl;
			}
			//cout<<"_vertices_of_mesh_"<<i<<"_generated_"<<endl;











	   		// texture Koordinaten aus Q3O Struktur auslesen und diese in this.texCoords Objekt Liste sichern!
			max = me->numberTextureCoordinates;// max textureCoordinates
			tmp->_texCoords.reserve(me->numberTextureCoordinates);
			for( int j = 0;j < max;j++ )
			{
				texUV = &me->textureCoordinates[j];// zugriff variable
				tmp->_texCoords.push_back( ( new TexCoordData( texUV->uv[0]  , texUV->uv[1] ) ) );
			}
			//cout<<"_texture_coordinates_of_mesh_"<<i<<"_generated_"<<endl;










			// normals aus Q3O Struktur auslesen und diese in this.normals Objekt Liste sichern!
			max = me->numberNormals;// max normals
			tmp->_normals.reserve(me->numberNormals);
			for( int j = 0;j < max;j++ )
			{
				//cout <<"NORMALS: [ " << vert->xyz[0] << " , " << vert->xyz[1] << " , " << vert->xyz[2] << " ]"<<endl;
				vert = &me->normals[j];// zugriff variable

				tmp->_normals.push_back( new Vector3( vert->xyz[0], vert->xyz[1],vert->xyz[2] ) );
				//cout<<"->    "<<vert->xyz[0]<<"|"<<vert->xyz[1]<<"|"<<vert->xyz[2]<<endl;
			}















			// faces aus Q3O Struktur auslesen und diese in this.vertices Objekt Liste sichern!
			max = me->numberFaces;// max faces
			tmp->_triangles.reserve(me->numberFaces);
			list<TriangleData*> transparencyTris;
			for( int j = 0;j < max;j++ )
			{
				//cout << j << endl;
				face = &me->faces[j];// zeiger auf auf aktuellen face das referenzen für die punkte enthält
				bool withTexCoords = false;

				if( header.numberTextures > 0 && me->numberTextureCoordinates > 0)
				{

					texFace = &me->textureIndices[j];// zeiger auf auf aktuellen face das referenzen für die tex koordinaten enthält
					//cout <<"1: "<< texFace->vertices[0]<<"2: "<< texFace->vertices[1]<<"3: "<< texFace->vertices[2]<<endl;
					if( texFace->vertices[0] >= 0 && texFace->vertices[1] >= 0 && texFace->vertices[2] >= 0 )
						withTexCoords = true;
				}

				if( withTexCoords )
				{// init triangle with texture
					//cout <<"T1: "<< *tmp->_texCoords.at( texFace->vertices[0])  << " <> T2: "<< *tmp->_texCoords.at( texFace->vertices[1]) << " <> T3: "<<*tmp->_texCoords.at( texFace->vertices[2]) <<endl;
					//cout << "MatIndices | "<< me->materialIndices[j] << endl;
					tri = new TriangleData(
											tmp->_vertices.at( face->vertices[0] ),// referenzübergabe der richtigen punkte
											tmp->_vertices.at( face->vertices[1] ),
											tmp->_vertices.at( face->vertices[2] ),
											tmp->_texCoords.at( texFace->vertices[0] ),// referenzübergabe der richtigen tex koordinaten
											tmp->_texCoords.at( texFace->vertices[1] ),
											tmp->_texCoords.at( texFace->vertices[2] ),
											_materials.at( me->materialIndices[j] ),// referenzübergabe des richtigen materials
											face->flags
					);
					if( IsVersionAtLeast (3,2) )
						tri->setNormal(tmp->_normals.at(j));// referenzübergabe der normalen
					else
						tri->ComputeNormal();
				}
				else
				{// init triangle without texture coordinates
					MaterialData* mat = NULL;
					//cout << "MatIndices | "<< me->materialIndices[j] << endl;
					if( _materials.size() >  me->materialIndices[j] )
						mat = _materials.at( me->materialIndices[j] );
					tri = new TriangleData(
											tmp->_vertices.at( face->vertices[0] ),// referenzübergabe der richtigen punkte
											tmp->_vertices.at( face->vertices[1] ),
											tmp->_vertices.at( face->vertices[2] ),
											mat,// referenzübergabe des richtigen materials
											face->flags
					);
					if( IsVersionAtLeast (3,2) )
						tri->setNormal(tmp->_normals.at(j));// referenzübergabe der normalen
					else
						tri->ComputeNormal();
				}
				if( tri->IsTransparency() )
				{
					meshIsTransparency = true;
					transparencyTris.push_back(tri);
				}
				else
					tmp->addTriangle(tri);
			}
			//cout<<"_tris_of_mesh_"<<i<<"_generated_"<<endl;

			// add transparenxy triangles at the end of the list
			for( list<TriangleData*>::iterator it = transparencyTris.begin();it != transparencyTris.end();it++ )
				tmp->addTriangle( (*it) );


			if( _checkRedundants )
				tmp->MergeVertices();

			for( unsigned int j = 0;j < tmp->_vertices.size();j++)
				tmp->_vertices.at(j)->ComputeNormal();
			for( unsigned int j = 0;j < tmp->_triangles.size();j++)
				tmp->_triangles.at(j)->ComputeEdges();
			//cout<<"_normals_of_vertices_in_mesh_"<<i<<"_computed_"<<endl;

			//cout << "Bounding Box of this Mesh"<<endl;
			//cout <<"Min >> { "<< boxMin.getX() << " - " << boxMin.getY() << " - " << boxMin.getZ() << " }"<<endl;
			//cout <<"Max >> { "<< boxMax.getX() << " - " << boxMax.getY() << " - " << boxMax.getZ() << " }"<<endl;
			//cout<<"_mesh_"<<i<<"_pushed_in_vectorList_"<<endl;

			if( meshIsTransparency )
			{
				//cout <<"TRansMesh PUT IN TRANS LIST"<<endl;
				transparencyMeshes.push_back(tmp);
			}
			else
			{
				addMesh(tmp);
			}
		}
		// add transparenxy triangles at the end of the list
		for( list<MeshData*>::iterator it = transparencyMeshes.begin();it != transparencyMeshes.end();it++ )
		{
			//cout <<"TRansMesh GET FFROM TRANS LIST"<<endl;
			addMesh( (*it) );
		}
		#if DEBUG2
	cout << ">>> Meshes Loaded in Structure"<<endl;
#endif
	}
	catch( ... )
	{
		cout << "exception while converting q3o to rawObjectData!!!"<<endl;
	}

	// normalen fuer die einzelenen vertices berechnen



	//free memory!!!
	for( int i = 0;i < header.numberMeshes;i++ )
	{
		delete meshes.at(i);
		#ifdef DEBUG
		cout<<"delete_mesh: "<<i<<endl;
		#endif

	}
	#ifdef DEBUG
	cout<<"delete_complete_mesh"<<endl;
	#endif

	for( int i = 0;i < header.numberMaterials;i++ )
	{
		delete materials.at(i);
		#ifdef DEBUG
		cout<<"delete_material: "<<i<<endl;
		#endif
	}
	#ifdef DEBUG
	cout<<"delete_complete_material"<<endl;
	#endif

	for( int i = 0;i < header.numberTextures;i++ )
	{
		delete textures.at(i);
		#ifdef DEBUG
		cout<<"delete_texture: "<<i<<endl;
		#endif
	}
	#ifdef DEBUG
	cout<<"delete_complete_texture"<<endl;
	#endif

	//delete header;
	cout << ">>> Object Loading Complete!!!"<<endl;

	return true;
};
#undef DEBUG

